/**
 * Wrapper class for the bing route service.
 * 
 * @author Kim Pommert
 * @version %I%, %G%
 */
qx.Class.define("qooxdoosample.microsoft.bing.maps.BRoutePlanner",
{
	extend:  qx.core.Object,
	implement: qooxdoosample.cocktail.maps.IRoutePlanner,
	
	/**
	 * Class constructor.
	 * Instantiates an object of that class.
	 */
	construct: function()
	{
		this.base(arguments);
	},
	
	statics:
    {
    	/**
    	 * To use the route services, a valid bing maps object
    	 * has to be present in the DOM.
    	 * This ID is used for a <div> element that is created and deleted
    	 * dynamically during the use of the service. 
    	 * A temporary map that provides the route services
    	 * will be deployed in that container.
    	 */
    	TMP_MAP_CONTAINER_ID: "tmpMap"
    },
    
    properties:
    {
    	/**
    	 * Bing maps object. The map object provides all route services.
    	 * This map is used temporarily to use bing's route service.
    	 * It cannot be used as a map in the application.
    	 * All method calls will be converted and sent to this object.
    	 */
    	bMap:
    	{
    		nullable: true,
    		init: null,
    		check: "VEMap"
    	},
    	
    	/**
    	 * This temporary div container is used to deploy the temporary
    	 * bing maps object in the DOM.
    	 * The map must be present in a valid DOM object to use 
    	 * the route services.
    	 * The container is created and removed dynamically when starting
    	 * a route request to this object. It has the ID that is
    	 * described in the constant TMP_MAP_CONTAINER_ID of this class.
    	 * The div is added as a child of the <body> tag.
    	 */
    	tmpDiv:
    	{
    		nullable: true,
    		init: null,
    		check: "Object"
    	}
    },
	
	members:
	{		
		/**
		 * Get a complete route from start to target point.
		 * The result provides a Polyline representation 
		 * and a step by step description of the route.
		 * 
		 * @param start		{String} The location/address of the start point
		 * @param target 	{String} The location/address of the end point
		 * @param callback 	{Function} The result will be sent to this callback function
		 * @see qooxdoosample.cocktail.maps.IRoutePlanner#getRoute()
		 */
		getRoute: function(start, target, callback)
		{
			this.__activateTmpMap();
			var map = this.getBMap();
  			 	
			var options = new VERouteOptions;
            
            options.DrawRoute = false; // do not draw the route on the map
            options.SetBestMapView = false; // do not change the view of the map
            options.DistanceUnit = VERouteDistanceUnit.Kilometer; // set unit to kilometers
            options.ShowDisambiguation = false; // Show no disambiguation dialog
            
            // callback function when route is determined
            options.RouteCallback = function(bRoute){ 
            
            	// load polyline and steps from result
            	var routeLeg = bRoute.RouteLegs[0];
            	var legs = routeLeg.Itinerary.Items;
            	var leg = null;
            	var bPoint = null;
            	var pointsArr = new Array();
            	
            	var position = null;
            	var step = null;
            	var stepsArr = new Array();
            	
            	for(i = 0; i < legs.length; i++){
            		// get the coordinates for the polyline
            		leg = legs[i];
            		bPoint = leg.LatLong;
            		position = new qooxdoosample.cocktail.util.LatLng(bPoint.Latitude, bPoint.Longitude);
            		pointsArr[i] = position;
            		
            		// create step object and set all data
            		step = new qooxdoosample.cocktail.util.Step(position);
    				step.setDescription(leg.Text);
    				step.setDistance(leg.Distance);
    				step.setDuration(leg.Time);
    				stepsArr[i] = step;
            	}
            	
            	// create polyline
            	var polyline = new qooxdoosample.cocktail.util.overlays.Polyline(pointsArr);
            	
            	// create route object
            	var route = new qooxdoosample.cocktail.util.Route(polyline);
    			route.setSteps(stepsArr);
    			
    			route.setDistance(bRoute.Distance * 1000);
    			route.setDuration(bRoute.Time);
    				
    			callback(route);
            }; 


			// start and target can either be Strings representing an address
			// or a LatLng object
			if(start instanceof qooxdoosample.cocktail.util.LatLng)
			{
				var startPoint = new VELatLong(start.getLatitude(), start.getLongitude());
				var targetPoint = new VELatLong(target.getLatitude(), target.getLongitude());
				map.GetDirections([startPoint, targetPoint], options);
			}
			else
			{
	 			map.GetDirections([start, target], options);
			}
			this.__deactivateTmpMap();
		},
		
		/**
		 * If the temporary bing maps object is not yet created, it will be
		 * set here first. The temporary div container for the map is created
		 * and added as a child of the <body> tag.
		 * 
		 * This method must be called at the beginning of every route
		 * request to the temporary map object, as that has to be
		 * deployed in a valid div container of the DOM!
		 */
		__activateTmpMap: function()
		{
			/*
			 * Bing Maps needs a valid Map object in a div container
			 * to provide the route planning services
			 * 
			 * -> temporary div will be created and after route generation removed from DOM
			 */
			if(this.getTmpDiv() == null){
				this.setTmpDiv(document.createElement('div'));
    			this.getTmpDiv().setAttribute('id', this.self(arguments).TMP_MAP_CONTAINER_ID);
			}
    		document.getElementsByTagName("body")[0].appendChild(this.getTmpDiv());
    		
    		if(this.getBMap() == null){
    			this.setBMap(new VEMap(this.self(arguments).TMP_MAP_CONTAINER_ID));
				this.getBMap().LoadMap();
				this.getBMap().HideDashboard();
    		}
		},
		
		/**
		 * Removes the temporary div container from the DOM.
		 * 
		 * This method must be called after every route request
		 * to remove the temporary map from the DOM.
		 */
		__deactivateTmpMap: function()
		{
			document.getElementsByTagName("body")[0].removeChild(this.getTmpDiv());
		}
		
	}
	
});